package com.roadmap.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionRedirect;
import org.apache.struts.actions.DispatchAction;

import com.roadmap.biz.common.IManager;
import com.roadmap.exception.EntityNotFoundException;
import com.roadmap.exception.InvalidQueryException;
import com.roadmap.exception.InvalidValueException;
import com.roadmap.exception.NullObjectException;
import com.roadmap.exception.ServerException;

public abstract class RdcDispatchAction extends DispatchAction implements
		IActionUtil {
	private final RdcActionImpl rdcAction;

	public RdcDispatchAction() {
		this.rdcAction = new RdcActionImpl(null);
	}

	public RdcDispatchAction(String smtFwrd) {
		this.rdcAction = new RdcActionImpl(smtFwrd);
	}

	public boolean checkPermission(HttpServletRequest request)
			throws NullObjectException, InvalidQueryException, ServerException,
			InvalidValueException, EntityNotFoundException {
		return rdcAction.checkPermission(request);
	}

	public ActionForward getErrorForward(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ActionErrors errors = new ActionErrors();
		ActionForward forward = null;
		boolean isCheckPassed = true;

		if (isFormSubmitted(request)) {
			forward = (getSmtForward() == null) ? mapping.getInputForward()
					: mapping.findForward(getSmtForward());

			ActionMessage msg = new ActionMessage(RdcErrorCode.RDCERR0009);
			errors.add(ActionErrors.GLOBAL_MESSAGE, msg);

			isCheckPassed = false;
		}
		else if (!isLoggedOn(request)) {
			ActionRedirect redirect = new ActionRedirect("/logon.do");
			redirect.setRedirect(true);
			forward = redirect;
			isCheckPassed = false;

			// ActionMessage msg = new ActionMessage(RdcErrorCode.RDCERR0001);
			// errors.add(ActionErrors.GLOBAL_MESSAGE, msg);
		}
		else if (!checkPermission(request)) {
			forward = mapping.findForward("getlock");
			isCheckPassed = false;
		}
		else if (isOwner(request)) {
			request.setAttribute(ActionConst.Visitor_Is_Owner, true);
		}

		// if the check is not passed, forward should not be NULL
		if (!isCheckPassed && forward == null) {
			throw new Exception();
		}

		if (!errors.isEmpty()) {
			this.saveErrors(request, errors);
		}

		// 不发生错误的情况下更新用户消息、通知等
		if (forward == null) {
			updateDataInSession(request);
		}

		return forward;
	}

	public String getSmtForward() {
		return rdcAction.getSmtForward();
	}

	public boolean isFormSubmitted(HttpServletRequest request) throws Exception {
		return rdcAction.isFormSubmitted(request);
	}

	public boolean isLoggedOn(HttpServletRequest request) {
		return rdcAction.isLoggedOn(request);
	}

	public boolean isOwner(HttpServletRequest request) {
		return rdcAction.isOwner(request);
	}

	public void removeCookie(HttpServletResponse response, String[] cooks) {
		rdcAction.removeCookie(response, cooks);
	}

	public void saveCookies(HttpServletResponse response, String[] cooks,
			String[] values, Boolean[] isEncrypted) {
		rdcAction.saveCookies(response, cooks, values, isEncrypted);
	}

	public void updateDataInSession(HttpServletRequest request)
			throws NullObjectException, ServerException {
		rdcAction.updateDataInSession(request);
	}

	/**
	 * set the UID stored in request with the one in session and redirect with
	 * current user's id
	 */
	protected ActionRedirect handleInvalidUser(HttpServletRequest request,
			String action) {
		return rdcAction.handleInvalidUser(request, action);
	}

	// public void encodingString(Object text) {
	// rdcAction.encodingString(text);
	// }

	/** view an item */
	public final ActionForward view(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward forward = getErrorForward(mapping, form, request,
				response);
		return (forward == null) ? doView(mapping, form, request, response)
				: forward;
	}

	protected abstract ActionForward doView(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception;

	/** create an item */
	public final ActionForward create(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward forward = getErrorForward(mapping, form, request,
				response);
		return (forward == null) ? doCreate(mapping, form, request, response)
				: forward;
	}

	protected ActionForward doCreate(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.getInputForward();
	};

	/** edit an item */
	public final ActionForward edit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward forward = getErrorForward(mapping, form, request,
				response);
		return (forward == null) ? doEdit(mapping, form, request, response)
				: forward;
	}

	protected ActionForward doEdit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.getInputForward();
	}

	/** delete an item */
	public final ActionForward delt(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward forward = getErrorForward(mapping, form, request,
				response);
		return (forward == null) ? doDelete(mapping, form, request, response)
				: forward;
	}

	protected ActionForward doDelete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.getInputForward();
	}

	/** list all items */
	public final ActionForward all(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionForward forward = getErrorForward(mapping, form, request,
				response);
		return (forward == null) ? doAll(mapping, form, request, response)
				: forward;
	}

	protected ActionForward doAll(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		return mapping.getInputForward();
	}

	/** get the user id from session */
	protected String getUIDFromSession(HttpServletRequest request) {
		return rdcAction.getUIDFromSession(request);
	}
	
	protected int getCurrentPageNum(HttpServletRequest request) {
		return rdcAction.getCurrentPageNum(request);
	}
	
	protected void createPagingInfoInRequest(HttpServletRequest request,
			IManager mgr) {
		rdcAction.createPagingInfoInRequest(request, mgr);
	}
}
